# -*- coding: utf-8 -*-
from __future__ import annotations

from abc import ABC, abstractmethod

from mqtt.consumer.event_models import QualityEvent
from common.logger import create_logger

logger = create_logger("recovery.strategy", "INFO")


class RecoveryStrategy(ABC):
	"""告警恢复检测策略"""

	@abstractmethod
	def is_recovered(self, event: QualityEvent, alarm_type: str) -> bool:
		raise NotImplementedError


class ThresholdBackToNormalStrategy(RecoveryStrategy):
	"""连续量阈值恢复策略：根据告警类型判断具体的恢复条件"""

	def is_recovered(self, event: QualityEvent, alarm_type: str) -> bool:
		# 首先检查消息质量必须是GOOD
		if event.quality != "GOOD":
			return False

		# 根据告警类型制定不同的恢复策略
		if alarm_type in ["TEMP_OVER", "HIGH_TEMP"]:
			# 温度告警：检查温度值是否回到正常范围(假设阈值为35°C)
			# 优先检查T1字段（单相表），然后检查temperature1/temperature2（三相表）
			temp_values = []
			
			# 检查T1字段（通常在raw_snapshot中）
			if hasattr(event, 'raw_snapshot') and event.raw_snapshot:
				t1_value = event.raw_snapshot.get('T1')
				if t1_value is not None:
					try:
						temp_values.append(float(t1_value))
						logger.debug(f"[恢复检查] {event.meter_code} T1温度: {t1_value}°C")
					except (ValueError, TypeError):
						logger.warning(f"[恢复检查] {event.meter_code} T1温度值转换失败: {t1_value}")
			
			# 检查temperature1和temperature2字段（event对象属性）
			temp1 = getattr(event, 'temperature1', None)
			temp2 = getattr(event, 'temperature2', None)
			if temp1 is not None:
				temp_values.append(temp1)
			if temp2 is not None:
				temp_values.append(temp2)
			
			if temp_values:
				max_temp = max(temp_values)
				is_recovered = max_temp <= 35.0  # 温度恢复到安全范围
				logger.info(f"[恢复检查] {event.meter_code} {alarm_type} 最高温度: {max_temp}°C, 恢复状态: {is_recovered}")
				return is_recovered
			else:
				logger.warning(f"[恢复检查] {event.meter_code} {alarm_type} 未找到温度字段，不自动恢复")
				return False

		elif alarm_type in ["OVER_VOLTAGE", "VOLTAGE_OVER"]:
			# 过电压告警：检查电压是否回到正常范围(假设阈值为250V)
			voltage = getattr(event, 'voltage', None)
			return voltage is not None and voltage <= 250.0

		elif alarm_type in ["OVER_CURRENT", "CURRENT_OVER"]:
			# 过电流告警：检查电流是否回到正常范围(假设阈值为100A)
			current = getattr(event, 'current', None)
			return current is not None and current <= 100.0

		elif alarm_type in ["OVER_POWER", "POWER_OVER", "OVER_LOAD"]:
			# 过功率告警：检查功率是否回到正常范围(假设阈值为10000W)
			watt = getattr(event, 'watt', None)
			return watt is not None and watt <= 10000.0

		elif alarm_type in ["LOW_VOLTAGE", "UNDER_VOLTAGE"]:
			# 欠电压告警：检查电压是否回到正常范围(假设阈值为200V)
			voltage = getattr(event, 'voltage', None)
			return voltage is not None and voltage >= 200.0

		elif alarm_type in ["TAMPER", "THREE-TAMPER", "SINGLE-TAMPER"]:
			# 非法开箱告警：检查hr字段是否为0（正常状态）
			# 对于三相电表检查 hr 字段，对于单相电表检查 HR 字段
			hr_value = None

			# 首先尝试三相电表的hr字段（小写）
			if 'hr' in event.raw_snapshot:
				hr_value = event.raw_snapshot.get('hr')
				logger.debug(f"[恢复检查] 三相电表 {event.meter_code} hr值: {hr_value}")
			# 然后尝试单相电表的HR字段（大写）
			elif 'HR' in event.raw_snapshot:
				hr_value = event.raw_snapshot.get('HR')
				logger.debug(f"[恢复检查] 单相电表 {event.meter_code} HR值: {hr_value}")

			if hr_value is not None:
				# hr=0或HR=0表示正常，hr=1或HR=1表示异常
				is_recovered = str(hr_value) == '0'
				logger.info(f"[恢复检查] {event.meter_code} {alarm_type} hr/HR={hr_value}, 恢复状态: {is_recovered}")
				return is_recovered
			# 如果没有hr/HR字段，不自动恢复
			logger.warning(f"[恢复检查] {event.meter_code} {alarm_type} 未找到hr/HR字段，不自动恢复")
			return False

		elif alarm_type == "COMM_LOST":
			# 通信中断告警：能收到正常数据就说明通信已恢复
			return True

		else:
			# 其他类型告警：默认策略是质量为GOOD即恢复
			return True


class WorkOrderCloseStrategy(ABC):
	"""工单关闭策略"""

	@abstractmethod
	def should_close_on_recovered(self) -> bool:
		raise NotImplementedError


class AutoCloseOnRecoveredStrategy(WorkOrderCloseStrategy):
	def should_close_on_recovered(self) -> bool:
		return True
